﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

using System.Reflection;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

using Sita.Presentation.Controllers;
//using Sita.Presentation.MVC.Code.Extensions;
using Sita.MainModule.Services;
//using Sita.Infrastructure.CrossCuting.IoC;
using System.IO;
using System.Net;

namespace Sita.Presentation.Helpers
{
    public static class HtmlHelperExtensions
    {
        //public static Models.UserSessionUser GetAuthenticatedUserData(this HtmlHelper helper)
        //{
        //    DefaultController ViewController;

        //    if (helper.ViewContext.Controller != null)
        //    {
        //        if (helper.ViewContext.Controller is DefaultController)
        //        {
        //            ViewController = (DefaultController)helper.ViewContext.Controller;

        //            if (ViewController.User.Identity.IsAuthenticated)
        //            {
        //                return ViewController.AuthenticatedUser.Data;
        //            }
        //        }
        //    }

        //    return new Models.UserSessionUser();
        //}

        //public static string GetEntityDisplayName(this HtmlHelper helper, Type objType, string propName)
        //{
        //    MetadataTypeAttribute ObjectMetadata;
        //    DisplayNameAttribute PropertyDisplayName;
        //    PropertyInfo PropertyData;

        //    ObjectMetadata = (MetadataTypeAttribute)objType.GetCustomAttributes(typeof(MetadataTypeAttribute), true).SingleOrDefault();

        //    if (ObjectMetadata != null)
        //    {
        //        PropertyData = ObjectMetadata.MetadataClassType.GetProperty(propName);

        //        if (PropertyData != null)
        //        {
        //            PropertyDisplayName = (DisplayNameAttribute)PropertyData.GetCustomAttributes(typeof(DisplayNameAttribute), true).SingleOrDefault();
        //            if (PropertyDisplayName != null && PropertyDisplayName.DisplayName != null)
        //            {
        //                return PropertyDisplayName.DisplayName;
        //            }
        //        }
        //    }

        //    return propName;
        //}

        //public static string Decode(this HtmlHelper helper, string encoded)
        //{
        //    return HttpUtility.HtmlDecode(encoded);
        //}

        public static string AuthenticateUrl(this HtmlHelper helper, string relativeUrl)
        {
            return helper.ViewContext.HttpContext.Response.ApplyAppPathModifier(relativeUrl);
        }

        //public static string GetResourceNameByID(this HtmlHelper helper, string resourceType, string resourceID)
        //{
        //    Controllers.ResourcesController RC;

        //    RC = new ResourcesController();
        //    ISIPDeviceService SIPDeviceService;

        //    SIPDeviceService = IoCFactory.Resolve<ISIPDeviceService>();

        //    if (resourceID != string.Empty)
        //    {
        //        if (resourceType == Resources.Data.BusinessUnitResourceTypes.ModemSIP)
        //        {
        //            return SIPDeviceService.GetSIPDeviceByObjectID(resourceID).Name;
        //        }
        //        if (resourceType == Resources.Data.BusinessUnitResourceTypes.Modem)
        //        {
        //            return ((Adecef.RoamFix.Domain.MainModule.Entities.Modem)RC.GetModemByObjectID(resourceID, false).Data).Name;
        //        }
        //        else if (resourceType == Resources.Data.BusinessUnitResourceTypes.SIM)
        //        {

        //        }
        //    }

        //    return string.Empty;
        //}

        public static string GetCommonContent(this HtmlHelper helper, string resource)
        {
            resource = ((Controller)helper.ViewContext.Controller).Url.Content("~/Content/Common/" + resource);

            return resource;
        }

        //public static DateTime UserDateTime(this HtmlHelper helper, DateTime originalDateTime)
        //{
        //    DefaultController ViewController;

        //    if (helper.ViewContext.Controller != null)
        //    {
        //        if (helper.ViewContext.Controller is DefaultController)
        //        {
        //            ViewController = (DefaultController)helper.ViewContext.Controller;

        //            if (ViewController.User.Identity.IsAuthenticated)
        //            {
        //                return originalDateTime.ToUserDateTime(
        //                    ViewController.AuthenticatedUser.Data.TimeZone,
        //                    ViewController.AuthenticatedUser.Data.DaylightSavingTime);
        //            }
        //        }
        //    }

        //    return originalDateTime;
        //}



        public static string GetThemeContent(this HtmlHelper helper, string resource)
        {
            DefaultController ViewController;
            string OriginalResource = resource;

            if (helper.ViewContext.Controller != null)
            {
                if (helper.ViewContext.Controller is DefaultController)
                {
                    ViewController = (DefaultController)helper.ViewContext.Controller;

                    if (ViewController.User.Identity.IsAuthenticated)
                    {
                        if (!resource.StartsWith("~") && !resource.StartsWith("/") && !resource.StartsWith(@"\"))
                        {
                            OriginalResource = "~/Content/{0}/" + resource;
                            resource = ViewController.Url.Content("~/Content/{0}/" + resource);
                        }

                        if (ViewController.AuthenticatedUser != null && File.Exists(helper.ViewContext.HttpContext.Server.MapPath(string.Format(OriginalResource, ViewController.AuthenticatedUser.Data.Theme))))
                        {
                            return string.Format(resource, ViewController.AuthenticatedUser.Data.Theme);
                        }
                        else
                        {
                            return string.Format(resource, "");
                        }

                    }
                }
            }

            return ((Controller)helper.ViewContext.Controller).Url.Content("~/Content/" + resource);
        }

        public static MvcHtmlString Image(this HtmlHelper helper, string imgSrc, string alt)
        {
            return Image(helper, imgSrc, alt, null);
        }

        public static MvcHtmlString Image(this HtmlHelper helper, string imgSrc, string alt, object htmlAttributes)
        {
            return Image(helper, imgSrc, alt, new RouteValueDictionary(htmlAttributes));
        }

        public static MvcHtmlString Image(this HtmlHelper helper, string imgSrc, string alt, IDictionary<string, object> htmlAttributes)
        {
            TagBuilder ImageTag;
            string SourceUrl;

            ImageTag = new TagBuilder("img");
            if (imgSrc.IndexOf("/") > -1 || imgSrc.IndexOf(@"\") > -1)
            {
                SourceUrl = imgSrc;
            }
            else
            {
                SourceUrl = GetThemeContent(helper, "Images/" + imgSrc);
            }

            if (htmlAttributes != null)
            {
                ImageTag.MergeAttributes(htmlAttributes, true);
            }

            ImageTag.Attributes.Add("src", SourceUrl);
            if (ImageTag.Attributes.ContainsKey("style"))
            {
                ImageTag.Attributes["style"] = ImageTag.Attributes["style"] + ";border: none;";
            }
            else
            {
                ImageTag.MergeAttribute("style", "border: none;");
            }

            return MvcHtmlString.Create(ImageTag.ToString());
        }


        public static MvcHtmlString ImageLink(this HtmlHelper helper, string imgSrc, string alt, string actionName)
        {
            return ImageLink(helper, imgSrc, alt, actionName, null);
        }

        public static MvcHtmlString ImageLink(this HtmlHelper helper, string imgSrc, string alt, string actionName, object routeValues)
        {
            string ControllerName;

            if (helper.ViewContext.RouteData.Values["Controller"] != null)
            {
                ControllerName = helper.ViewContext.RouteData.Values["Controller"].ToString();
            }
            else
            {
                ControllerName = string.Empty;
            }

            return ImageLink(helper, imgSrc, alt, actionName, ControllerName, routeValues, null, null);
        }

        public static MvcHtmlString ImageLink(this HtmlHelper helper, string imgSrc, string alt, string actionName, string controllerName)
        {
            return ImageLink(helper, imgSrc, alt, actionName, controllerName, null, null, null);
        }

        public static MvcHtmlString ImageLink(this HtmlHelper helper, string imgSrc, string alt, string actionName, string controllerName,
            object routeValues, object linkHtmlAttributes, object imgHtmlAttributes)
        {
            return ImageLink(helper, imgSrc, alt, actionName, controllerName, routeValues,
                new RouteValueDictionary(linkHtmlAttributes), new RouteValueDictionary(imgHtmlAttributes));
        }



        public static MvcHtmlString ImageLink(this HtmlHelper helper, string imgSrc, string alt, string actionName, string controllerName,
            object routeValues, IDictionary<string, object> linkHtmlAttributes, IDictionary<string, object> imgHtmlAttributes)
        {
            TagBuilder ImageTag;
            TagBuilder LinkTag;
            string LinkUrl;
            string SourceUrl;

            ImageTag = new TagBuilder("img");
            if (imgSrc.IndexOf("/") > -1 || imgSrc.IndexOf(@"\") > -1)
            {
                SourceUrl = imgSrc;
            }
            else
            {
                SourceUrl = GetThemeContent(helper, "Images/" + imgSrc);
            }

            ImageTag.MergeAttribute("src", SourceUrl);
            ImageTag.MergeAttribute("style", "border: none;");

            if (imgHtmlAttributes != null)
            {
                ImageTag.MergeAttributes(imgHtmlAttributes, true);
            }

            LinkUrl = ((Controller)helper.ViewContext.Controller).Url.Action(actionName, controllerName, routeValues);

            LinkTag = new TagBuilder("a");
            LinkTag.MergeAttribute("href", LinkUrl);

            if (imgSrc != "") //Si la imagen viene x estilo, no la dibujo.
            {
                LinkTag.InnerHtml = ImageTag.ToString();
            }
            if (linkHtmlAttributes != null)
            {
                LinkTag.MergeAttributes((IDictionary<string, object>)linkHtmlAttributes, true);
            }

            return MvcHtmlString.Create(LinkTag.ToString());
        }


        public static MvcHtmlString ButtonLink(this HtmlHelper helper, string buttonText, string actionName, object linkHtmlAttributes, object buttonHtmlAttributes)
        {
            string ControllerName;

            if (helper.ViewContext.RouteData.Values["Controller"] != null)
            {
                ControllerName = helper.ViewContext.RouteData.Values["Controller"].ToString();
            }
            else
            {
                ControllerName = string.Empty;
            }

            return ButtonLink(helper, buttonText, actionName, ControllerName, null, linkHtmlAttributes, buttonHtmlAttributes);
        }

        public static MvcHtmlString ButtonLink(this HtmlHelper helper, string buttonText, string actionName, string controllerName,
            object routeValues, object linkHtmlAttributes, object buttonHtmlAttributes)
        {
            TagBuilder ButtonTag;
            TagBuilder LinkTag;
            string LinkUrl;


            ButtonTag = new TagBuilder("input");
            ButtonTag.MergeAttribute("type", "button");
            ButtonTag.MergeAttribute("value", buttonText);
            if (buttonHtmlAttributes != null)
            {
                ButtonTag.MergeAttributes(new RouteValueDictionary(buttonHtmlAttributes), true);
            }


            LinkUrl = ((Controller)helper.ViewContext.Controller).Url.Action(actionName, controllerName, routeValues);

            LinkTag = new TagBuilder("a");
            LinkTag.MergeAttribute("href", LinkUrl);
            LinkTag.InnerHtml = ButtonTag.ToString();
            if (linkHtmlAttributes != null)
            {
                LinkTag.MergeAttributes(new RouteValueDictionary(linkHtmlAttributes), true);
            }

            return MvcHtmlString.Create(LinkTag.ToString());
        }
        public static MvcHtmlString ValidationImageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, System.Linq.Expressions.Expression<Func<TModel, TProperty>> expression, string imageURL)
        {
            return htmlHelper.ValidationImageFor<TModel, TProperty>(expression, imageURL, null, ((IDictionary<string, object>)new RouteValueDictionary()));
        }

        public static MvcHtmlString ValidationImageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, System.Linq.Expressions.Expression<Func<TModel, TProperty>> expression, string imageURL, string validationMessage, object htmlAttributes)
        {
            return htmlHelper.ValidationImageFor<TModel, TProperty>(expression, imageURL, validationMessage, htmlAttributes, false);
        }

        public static MvcHtmlString ValidationImageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, System.Linq.Expressions.Expression<Func<TModel, TProperty>> expression, string imageURL, string validationMessage, object htmlAttributes, bool isTooltipBelow)
        {
            return htmlHelper.ValidationImageHelper(ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData), ExpressionHelper.GetExpressionText(expression), imageURL, validationMessage, new RouteValueDictionary(htmlAttributes), isTooltipBelow);
        }

        private static MvcHtmlString ValidationImageHelper(this HtmlHelper htmlHelper, ModelMetadata modelMetadata, string expression, string imageURL, string validationMessage, IDictionary<string, object> htmlAttributes, bool isTooltipBelow)
        {
            string FullHtmlFieldName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression);
            FormContext FormContextForClientValidation;
            if (!htmlHelper.ViewContext.ClientValidationEnabled)
            {
                FormContextForClientValidation = null;
            }
            else
            {
                FormContextForClientValidation = htmlHelper.ViewContext.FormContext;
            }
            if (!htmlHelper.ViewData.ModelState.ContainsKey(FullHtmlFieldName) && (FormContextForClientValidation == null))
            {
                return null;
            }
            ModelState ModelState = htmlHelper.ViewData.ModelState[FullHtmlFieldName];
            ModelErrorCollection Errors = (ModelState == null) ? null : ModelState.Errors;
            ModelError Error = ((Errors == null) || (Errors.Count == 0)) ? null : Errors[0];
            if ((Error == null) && (FormContextForClientValidation == null))
            {
                return null;
            }

            TagBuilder SpanBuilder = new TagBuilder("span");
            SpanBuilder.AddCssClass((Error != null) ? HtmlHelper.ValidationMessageCssClassName : HtmlHelper.ValidationMessageValidCssClassName);
            SpanBuilder.Attributes.Add("style", "display:none");

            if (!string.IsNullOrEmpty(validationMessage))
            {
                SpanBuilder.SetInnerText(validationMessage);
            }
            else if (Error != null)
            {
                SpanBuilder.SetInnerText(GetUserErrorMessageOrDefault(htmlHelper.ViewContext.HttpContext, Error, ModelState));
            }
            if (FormContextForClientValidation != null)
            {
                if (htmlAttributes.ContainsKey("id"))
                {
                    SpanBuilder.GenerateId(htmlAttributes["id"] + ".validationMessage");
                }
                else
                {
                    SpanBuilder.GenerateId(FullHtmlFieldName + ".validationMessage");
                }
                FieldValidationMetadata Metadata = ApplyFieldValidationMetadata(htmlHelper, modelMetadata, FullHtmlFieldName);
                Metadata.ReplaceValidationMessageContents = string.IsNullOrEmpty(validationMessage);
                Metadata.ValidationMessageId = SpanBuilder.Attributes["id"];
            }

            TagBuilder DivTooltipBuilder = new TagBuilder("div");
            if (isTooltipBelow)
            {
                DivTooltipBuilder.AddCssClass("tooltipBelow");
            }
            else
            {
                DivTooltipBuilder.AddCssClass("tooltipAbove");
            }
            if (htmlAttributes.ContainsKey("id"))
            {
                DivTooltipBuilder.GenerateId(htmlAttributes["id"] + ".title.container");
            }
            else
            {
                DivTooltipBuilder.GenerateId(FullHtmlFieldName + ".title.container");
            }

            DivTooltipBuilder.Attributes.Add("name", FullHtmlFieldName + ".title.container");

            string ID = SpanBuilder.Attributes["id"].Remove(SpanBuilder.Attributes["id"].LastIndexOf(SpanBuilder.IdAttributeDotReplacement));

            string SpanMessageTag = SpanBuilder.ToString(TagRenderMode.Normal);
            string ImageErrorTag = Image(htmlHelper, imageURL, "", new
            {
                style = "display:none; cursor:pointer",
                id = "img" + ID,
                name = "img" + FullHtmlFieldName
            }).ToString();

            string DivTooltipTag = DivTooltipBuilder.ToString(TagRenderMode.Normal);

            return MvcHtmlString.Create(SpanMessageTag + ImageErrorTag + DivTooltipTag);
        }

        private static string GetUserErrorMessageOrDefault(HttpContextBase httpContext, ModelError error, ModelState modelState)
        {
            if (!string.IsNullOrEmpty(error.ErrorMessage))
            {
                return error.ErrorMessage;
            }
            if (modelState == null)
            {
                return null;
            }
            string Str = (modelState.Value != null) ? modelState.Value.AttemptedValue : null;
            return "Error!";
        }

        private static FieldValidationMetadata ApplyFieldValidationMetadata(HtmlHelper htmlHelper, ModelMetadata modelMetadata, string modelName)
        {
            FieldValidationMetadata ValidationMetadataForField = htmlHelper.ViewContext.FormContext.GetValidationMetadataForField(modelName, true);
            foreach (ModelClientValidationRule[] Rules in from v in ModelValidatorProviders.Providers.GetValidators(modelMetadata, htmlHelper.ViewContext) select v.GetClientValidationRules())
            {
                foreach (ModelClientValidationRule Rule in Rules)
                {
                    ValidationMetadataForField.ValidationRules.Add(Rule);
                }
            }
            return ValidationMetadataForField;
        }
    }
}